# coding: utf-8
import functools


"""
修饰器模式通常用于扩展一个对象的功能
"""
def memoize(fn):
    known = dict()
    @functools.wraps(fn)
    def memoizer(*args):
        if args not in known:
            known[args] = fn(*args)
        return known[args]
    return memoizer

@memoize
def nsum(n):
    '''返回前n个数字的和'''
    assert(n >= 0), 'n must be >= 0'
    return 0 if n == 0 else n + nsum(n-1)

@memoize
def fibonacci(n):
    '''返回斐波那契数列的第n个数'''
    assert(n >= 0), 'n must be >= 0'
    return n if n in (0, 1) else fibonacci(n-1) + fibonacci(n-2)

if __name__ == '__main__':
    # timeit统计程序执行时间
    from timeit import Timer

    measure = [
            {
                "exec": "fibonacci(10)",
                "import": "fibonacci",
                "func": fibonacci
            },
            {
                "exec": "nsum(200)",
                "import": "nsum",
                "func": nsum
            }
        ]

    for m in measure:
        t = Timer('{}'.format(m['exec']), 'from __main__ import {}'.format(m['import']))
        print('name: {}, doc: {}, executing: {}, time: {}'.format(m['func'].__name__, m['func'].__doc__, m['exec'], t.timeit()))